package com.sicau.socialpracticesystem.controller;


import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.event.AnalysisEventListener;
import com.sicau.socialpracticesystem.common.constant.UrlConstants;
import com.sicau.socialpracticesystem.common.returning.ResultData;
import com.sicau.socialpracticesystem.common.returning.ResultStatus;
import com.sicau.socialpracticesystem.config.aop.ValidateAspect;
import com.sicau.socialpracticesystem.config.dozer.DozerUtils;
import com.sicau.socialpracticesystem.entity.param.pointsitem.PointItemQueryParam;
import com.sicau.socialpracticesystem.entity.param.pointsitem.PointsItemUploadData;
import com.sicau.socialpracticesystem.entity.po.PointsItem;
import com.sicau.socialpracticesystem.entity.po.User;
import com.sicau.socialpracticesystem.entity.vo.PageDataVO;
import com.sicau.socialpracticesystem.service.PointsItemService;
import com.sicau.socialpracticesystem.service.PointsService;
import com.sicau.socialpracticesystem.service.SqlService;
import com.sicau.socialpracticesystem.util.BatchSqlGenerator;
import com.sicau.socialpracticesystem.util.ExcelUtil;
import com.sicau.socialpracticesystem.util.PageUtil;
import com.sicau.socialpracticesystem.util.UserContext;
import com.sicau.socialpracticesystem.util.upload.ExcelCheckErrDto;
import com.sicau.socialpracticesystem.util.upload.ExcelListenerHelper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 * 积分项表 前端控制器
 * </p>
 *
 * @author sxt && ttxxi
 * @since 2021-04-26
 */
@RestController
@PreAuthorize("isAuthenticated()")
@RequestMapping(UrlConstants.POINTS_ITEM_PREFIX)
@Slf4j
@Api(tags = "积分项相关")
public class PointsItemController {

    @Resource
    private DozerUtils dozerUtils;

    @Resource
    private PointsItemService pointsItemService;

    @Resource
    private SqlService sqlService;

    @Resource
    private PointsService pointsService;

    /**
     * 批量导入记录
     *
     * @param file file
     * @return return
     */
    @PostMapping("/upload")
    @ApiOperation(value = "批量导入记录", notes = "批量导入记录")
    public ResultData<List<ExcelCheckErrDto<PointsItemUploadData>>> upload(@ApiParam(name = "file", value = "文件名") MultipartFile file) {

        if (!ExcelUtil.isExcel(file)) {
            return new ResultData().FAILED().setResultIns("上传文件有误");
        }

        User user = UserContext.get();

        ExcelListenerHelper<PointsItemUploadData> builder = new ExcelListenerHelper<>();

        /*
         * key为学号，value为总积分
         */
        HashMap<Integer, Double> totalPointsMap = new HashMap<>();

        AnalysisEventListener<PointsItemUploadData> listener = builder.getListener(uploadDataList -> {
            List<PointsItem> list = dozerUtils.mapList(uploadDataList, PointsItem.class);
            for (PointsItem item : list) {
                double addPoints = item.getSecondLessonValue() * 5;
                item.setPoints(addPoints);
                totalPointsMap.merge(item.getUserNumber(), addPoints, Double::sum);
            }
            sqlService.executeInsert(BatchSqlGenerator.getBatchSqlStatement(PointsItem.class, list));
            return uploadDataList.size();
        });

        BufferedInputStream stream = null;
        try {
            stream = new BufferedInputStream(file.getInputStream());
            EasyExcel.read(stream, PointsItemUploadData.class, listener).sheet().doRead();
            List<ExcelCheckErrDto<PointsItemUploadData>> errList = builder.getErrList();
            Integer successCount = builder.getSuccessCount();

            //更新总积分
            pointsService.addPointsByUserNumber(totalPointsMap);

            //有错误信息需要输出错误信息
            if (errList.isEmpty()) {
                return new ResultData("成功导入" + successCount + "条！", ResultStatus.SUCCESS.getStatus(),  successCount);
            } else {
                return new ResultData("成功导入" + successCount + "条！", ResultStatus.SUCCESS.getStatus(),  errList);
            }
        } catch (IOException e) {
            log.error("读取文件 [{}] 失败", file.getOriginalFilename());
            return new ResultData().FAILED().setResultIns("上传文件失败");
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    log.error("io流关闭失败", e);
                }
            }
        }
    }

    @GetMapping("/page")
    @ApiOperation("分页查询")
    @ValidateAspect.ParamValidate
    public ResultData<PageDataVO<PointsItem>> queryPage(@Valid PointItemQueryParam pointItemQueryParam, BindingResult bindingResult){
        return new ResultData<PageDataVO<PointsItem>>().OK().setObj(PageUtil.convert(pointsItemService.queryByPage(pointItemQueryParam)));
    }
}

